package java.lang;

/**
 * @Auther: luanmihun
 * @Date: 2018/7/30 17:02
 * @Description:java.lang包下面的Object里面的方法分析，对里面的方法测试类在main.test.lang.ObjectMethodTest.java
 * Object为所有类的父类，是在jdk1.0中就定义好的
 * 目前没有说明的问题clone()方法的深入理解和toHexString()方法说明,线程方面的说明
 */
public class ObjectMethodExplain {

    /**
     * native是关键字。它一般在本地声明，异地用C和C++来实现。它的声明有几点要注意：
     * 1）native与访问控制符前后的关系不受限制。
     * 2）必须在返回类型之前。
     * 3）它一般为非抽象类方法。
     * 4）native方法在异地实现，象抽象方法一样，所以没有方法体，以分号结束
     *
     * 说明：.剩下的.dll文件里面的内容会做一些深度的研究，后续会进行更新
     */


    //在Object加载的时候会加载registerNatives()方法，并调用.dll文件
    private static native void registerNatives();
    static {
        registerNatives();
    }


    /**
     * 返回运行时候的类因为被final修饰所以不能重写,在main函数中进行了测试，其中返现两个错误
     * 1) java.lang.SecurityException: Prohibited package name: java.lang项目中不能以java.什么对包名进行调用
     * 2) java.lang.UnsatisfiedLinkError: ObjectMethod.registerNatives()V是因为在调用的时候应当现加载registerNatives()方法
     *    而在以上面代码中我们写了一个registerNatives()方法，所以无法运行，需要注释掉registerNatives()方法
     */
    //public final native Class<?> getClass();

    /**
     * 返回对象的哈希代码值，支持哈希表，例如：java.util.HashMap
     * hashCode返回的并不一定是对象的（虚拟）内存地址，具体取决于运行时库和JVM的具体实现。
     * 特性如下：
     * 1） 一致性（consistent），在程序的一次执行过程中，对同一个对象必须一致地返回同一个整数。
     * 2） 如果两个对象通过equals(Object)比较，结果相等，那么对这两个对象分别调用hashCode方法应该产生相同的整数结果，
     *     这里equals和hashCode说的都是Object类的
     * 3） 如果两个对象通过java.lang.Object.equals(java.lang.Ojbect)比较，结果不相等，不必保证对这两个对象分别调用hashCode也返回两个不相同的整数
     */
    public native int hashCode();

    /**
     * 比较两个对象hashCode值是否相同
     * @param obj  传入的对象
     * @return boolean类型
     */
    public boolean equals(Object obj) {
        return (this == obj);
    }

    /**
     * 创建并返回此对象的副本，这个方法的调用类需要实现Cloneable接口，这里面涉及到深浅copy，会在后面进行说明，如果没有实现Cloneable类就不抛出CloneNotSupportedException异常
     * @return
     * @throws CloneNotSupportedException
     */
    protected native Object clone() throws CloneNotSupportedException;

    /**
     * 返回一个对象名以及所在的包名+@+hashCode值，后面会对toHexString()方法进行说明
     * @return
     */
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    /**
     * 唤醒在这个对象的监视器上等待的单个线程
     */
    //public final native void notify();

    /**
     * 唤醒在这个对象的监视器上等待的所有线程
     */
    //public final native void notifyAll();

    /**
     * 使当前线程处于等待的状态知道被notify()，方法和notifyAll()方法所调用
     * @param timeout  最大等待时间
     */
    //public final native void wait(long timeout) throws InterruptedException;


    /**
     * 当前线程处于等待的状态知道被notify()，方法和notifyAll()方法所调用
     * @param nanos  额外的时间，在纳秒范围0- 999999
     * @param timeout 最大等待时间
     *
     */
//    public final void wait(long timeout, int nanos) throws InterruptedException {
//        if (timeout < 0) {
//            throw new IllegalArgumentException("timeout value is negative");
//        }
//
//        if (nanos < 0 || nanos > 999999) {
//            throw new IllegalArgumentException(
//                    "nanosecond timeout value out of range");
//        }
//
//        if (nanos > 0) {
//            timeout++;
//        }
//
//        wait(timeout);
//    }

    /**
     * 当前线程处于等待的状态知道被notify()，方法和notifyAll()方法所调用,默认时间为0
     */
//    public final void wait() throws InterruptedException {
//        wait(0);
//    }


    /**
     * 垃圾回收机制所要用的方法
     * @throws Throwable
     */
    protected void finalize() throws Throwable { }

}
